package com.zds.scm.common.dao;

import org.apache.log4j.Logger;

import com.zds.scm.common.util.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import java.util.ArrayList;
import java.util.List;


/**
 * 抽象DAO类,JDBC抽象通用DAO类
 * 时间:
 * @version 1.0
 * @author yhm
 * 
 */
public abstract class AbstractDAOImpl<T> {

	public static final Logger	logger	= Logger.getLogger(AbstractDAOImpl.class);
	
	abstract protected T rowMapper(ResultSet rs) throws SQLException;
	/**
	 * 查询实体个数
	 * @param sql
	 * @param args
	 * @return
	 */
	public int findEntityCount(String sql, Object[] args) {
		logger.debug("执行语句:"+sql);
		logger.debug("参数个数:"+args.length);
		
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			logger.info("开始查找满足条件实体个数");
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++)
				ps.setObject(i + 1, args[i]);
			rs = ps.executeQuery();
			int icount = 0;
			if(rs.next()){
			   icount=rs.getInt(1);
			}
			logger.info("结束查找满足条件实体个数");
			return icount;
		} catch (SQLException e) {
			logger.error("查询满足条件实体个数出现错误:"+e.getMessage());
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
	/**
	 * 查询方法.只查询一条记录
	 * 
	 * @param sql
	 * @param args
	 * @return
	 */
	public T findEntity(String sql, Object[] args) {
		logger.debug("执行语句:"+sql);
		logger.debug("参数个数:"+args.length);
		
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			logger.info("开始查找单个实体");
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++)
				ps.setObject(i + 1, args[i]);
			rs = ps.executeQuery();
			T obj = null;
			if (rs.next()) {
				obj = rowMapper(rs);
			}
			logger.info("结束查找单个实体");
			return obj;
		} catch (SQLException e) {
			logger.error("查询单个实体出现错误:"+e.getMessage());
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
	
	/**
	 * 查询结果返回多条记录时使用
	 * 
	 * @param sql
	 * @param args
	 * @return 得到的实体列表
	 */
	public List<T> findEntitys(String sql, Object[] args) {
		logger.debug("执行语句:"+sql);
		logger.debug("参数个数:"+args.length);
		
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<T> lt=new ArrayList<T>();
		try {
			logger.info("开始查找多个实体");
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++)
				ps.setObject(i + 1, args[i]);
			rs = ps.executeQuery();
			while (rs.next()) {
				lt.add(rowMapper(rs));
			}
			logger.info("结束查找多个实体");
			return lt;
		} catch (SQLException e) {
			logger.error("查询多个实体出现错误:"+e.getMessage());
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
	/**
	 * 执行修改、删除，增加(指定主键时使用)实体的SQL语句
	 * 
	 * @param sql
	 * @param args
	 * @return
	 */
	public int updateEntity(String sql, Object[] args) {
		logger.debug("执行语句:"+sql);
		logger.debug("参数个数:"+args.length);
		
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int result=0;
		try {
			logger.info("开始增删改实体");
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql);
			for(int i = 0; i < args.length; i++)
				ps.setObject(i + 1, args[i]);
			result=ps.executeUpdate();
			logger.info("结束增删改实体");
			return result;
		} catch (SQLException e) {
			logger.error("增删改实体出现错误:"+e.getMessage());
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
	
	/**
	 * 只插入1条数据,插入数据时使用,只用于有自增主键的表的数据插入
	 * 如果表格没有自增主键那么会返回0
	 * 
	 * @param sql  需要执行的SQL语句
	 * @param args 输入的参数
	 * @param pKey 返回的主键值
	 * @return 返回值为主键的自增长值
	 */
	public int insertEntity(String sql, Object[] args) {
		logger.debug("执行语句:"+sql);
		logger.debug("参数个数:"+args.length);
		
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int pKey=0;
		try {
			logger.info("开始新增自增主键的实体");
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			for (int i = 0; i < args.length; i++)
				ps.setObject(i + 1, args[i]);
			ps.executeUpdate();        // 执行插入操作
			rs = ps.getGeneratedKeys();// 获取产生的自增长字段
			if(rs.next()){
			  pKey=rs.getInt(1);
			}
			logger.info("结束新增自增主键的实体");
			logger.debug("自增主键是:"+Integer.toString(pKey));
			return pKey;
		} catch (SQLException e) {
			logger.error("增加实体出现错误:"+e.getMessage());
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
}
